#ifndef __BOSS_TOOLS_H__
#define __BOSS_TOOLS_H__

#include "ref_obj_qi_ptr.h"
#include "iservice_locator.h"
#include "exceptions.h"
#include "../components/common/include/cls_ids.h"
#include "../components/common/include/class_factory_ifaces.h"


namespace Boss
{

  RefObjPtr<IBase> GetEnviroment();

  namespace Tools
  {
    BOSS_DECLARE_RUNTIME_EXCEPTION(Tools)

      inline RefObjPtr<IServiceLocator> GetServiceLocator()
    {
      RefObjPtr<IBase> Env = GetEnviroment();
      if (!Env.Get())
        throw ToolsException("The enviroment is absent");
      RefObjQIPtr<IServiceLocator> ServiceLocator(Env);
      if (!ServiceLocator.Get())
        throw ToolsException("Can't get serviceLocator");
      return ServiceLocator;
    }

    inline RefObjPtr<Boss::IClassFactory> GetClassFactor()
    {
      RefObjQIPtr<IServiceLocator> ServiceLocator = GetServiceLocator();
      RefObjPtr<IBase> FactoryObject;
      if (ServiceLocator->GetService(BOSS_CLSID_ICLASSFACTORYIMPL, FactoryObject.GetPPtr()) != rcOk)
        throw ToolsException("ClassFactory not found");
      RefObjQIPtr<Boss::IClassFactory> Factory(FactoryObject);
      if (!Factory.Get())
        throw ToolsException("Interface IClassFactory not found");
      return Factory;
    }

    template <typename T>
    inline RefObjPtr<T> CreateObject(TGuid coClassId)
    {
      RefObjPtr<IBase> Instance;
      if (GetClassFactor()->CreateObject(coClassId, reinterpret_cast<TPtr *>(Instance.GetPPtr())) != rcOk)
        throw ToolsException("Can't create object");
      RefObjQIPtr<T> Ret(Instance);
      if (!Ret.Get())
        throw ToolsException("Interface not found");
      return Ret;
    }

  }

}

#endif  // !__BOSS_TOOLS_H__
